#include <stdio.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <stdlib.h>
#include "client.h"
#include "main.h"


#define VOICE_FILE "/root/hcc/wav/1.wav"
//#define VOICE_FILE "/root/hcc/wav/1.bmp"

int sockfd; //保存创建的流式套接字的文件描述符
int id; 

/* 
    client_init: 客户端初始化
    @ip: 客户端连接的服务器的ip
    @port: 服务器监听的端口号
    返回值：
        成功 0
        失败 -1
*/
int client_init(char *ip, short port)
{
    // //1.创建一个套接字  socket
    // sockfd = socket(AF_INET, SOCK_STREAM, 0);
    // if (-1 == sockfd)
    // {
    //     perror("socket create fail");
    //     return -1;
    // }

    // //2. connect 连接服务器，指定服务器的ip和端口
    // struct sockaddr_in server_addr; //指定要绑定的服务器的ip及端口
    // server_addr.sin_family = AF_INET; //指定ipv4
    // server_addr.sin_port = htons(port); //指定端口号，把端口号的主机字节序转换为网络字节序
    // server_addr.sin_addr.s_addr = inet_addr(ip); //指定ip， 点分式的ip转  
    // int ret = connect(sockfd, (struct sockaddr *)&server_addr, (socklen_t)sizeof(server_addr));
    // if (ret == -1)
    // {
    //     perror("connect fail");
    //     close(sockfd);
    //     return -1;
    // }


    // int sock = 0;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[1024] = {0};

    // 创建socket文件描述符
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Socket creation error \n");
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    // 将IP地址转换为二进制形式
    if (inet_pton(AF_INET, "192.168.31.100", &serv_addr.sin_addr) <= 0) {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    // 连接服务器
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("\nConnection Failed \n");
        return -1;
    }

}

/*
    transport_voice_file_to_server: 发送语音文件给服务端
    返回值：
        int
        成功 0
        失败 -1
*/
int transport_voice_file_to_server(void)
{
    //1.打开音频文件
    int voice_fd = open(VOICE_FILE, O_RDWR);
    if (-1 == voice_fd)
    {
        perror("open voice fail");
        return -1;
    }

    //2.先给服务器发送文件的大小
    int count = lseek(voice_fd, 0, SEEK_END); //光标偏移到文件末尾，计算字节数
    write(sockfd, &count, 4);

    //3.读取音频文件的内容，并把读取到的音频文件的内容发送到与服务器建立连接的套接字文件描述符上
    lseek(voice_fd, 0, SEEK_SET); //计算完文件大小后重新把光标定位到开头
    while(1)
    {
        
        char buf[128] = {0};
        int ret = read(voice_fd, &buf, sizeof(buf));//从语音文件中读
        if (-1 == ret)
        {
            perror("read fail");
            close(voice_fd);
            return -1;
        }
        else if(ret > 0)  //读成功，写到与服务器通信的套接字文件描述符中
        {
            write(sockfd, &buf, ret);
        }
        else if(ret == 0) // 读完了，已经读到了末尾
        {
            break;
        }   
    }

    //4.关闭音频文件
    close(voice_fd);
    return 0;
}

/*
    voice_logic: 语音识别逻辑
    返回值：
        void
*/
void voice_logic(void)
{

    	//阻塞你按回车
		printf("please enter 'enter' to record\n");
		getchar();
		//弄你的文件
		printf("please record for 4 seconds........\n");

    //1. 执行录音指令来获得指定的音频文件
    char voice_file_cmd[128] = {0};
    sprintf(voice_file_cmd ,"arecord -d4 -c1 -r16000 -traw -fs16_LE %s", VOICE_FILE);
    system(voice_file_cmd); //指令执行成功，得到一个宏定义 VOICE_FILE 指定的文件名

    //2. 把音频文件发送给服务器
    transport_voice_file_to_server();

    //3.接收服务器的识别后的id号，接收识别后的结果
    read(sockfd, &id, 4);
}


//<callstart>:打开电子相册!id(1)|上一张!id(2)|下一张!id(3)|退出!id(4)|返回!id(4)|环境监测!id(5);
void client_recv_id_tochange(){
    char buf[16] = {0};
    read(sockfd ,&id ,4);
    printf("recv_id_tochange:id = %d\n", id);
    //int idd = atoi(buf);
    switch (id)
    {
    case 1:
        mode = 1;
        break;
    case 2:
        show = show->prev;
        break;
    case 3:
        show = show->next;
        break;
    case 4:
        mode = 2;
        break;
    case 5:
        mode = 0;
        break;
    case 6:
        pause_album = 1;//开始播放电子相册
        break;
    case 7:
        pause_album = 0;//暂停播放
        break;
    
    default:
        break;
    }
}

void *client_pid(){

    while (1)
    {
        voice_logic();
        int ret = transport_voice_file_to_server();
        if(ret == -1) {
            perror("transport_voice_file_to_server failed");
            continue;
        }
        client_recv_id_tochange();
    }
    

}
